package core;

import java.util.ArrayList;
import java.util.Random;

public class Room {
	/* How big can be the room */
	private static final int MIN_LONG_SIDE = 10;
	private static final int MAX_LONG_SIDE = 25;
	private static final int MIN_SHORT_SIDE = 10;
	private static final int MAX_SHORT_SIDE = 20;

	/* How big is the room */
	private int longSide;
	private int shortSide;

	private ArrayList<Wall> limits = new ArrayList<Wall>();

	/* Where is the entrance and the exit */
	private Entrance entrance;
	private Exit exit;

	/* Matrix of all the elements of the room */
	private Element matrix[][];

	public Room() {
		Random randomGen = new Random();
		longSide = MIN_LONG_SIDE
				+ randomGen.nextInt(MAX_LONG_SIDE - MIN_LONG_SIDE);
		shortSide = MIN_SHORT_SIDE
				+ randomGen.nextInt(MAX_SHORT_SIDE - MIN_SHORT_SIDE);
		matrix = new Element[shortSide][longSide];
		entrance = new Entrance(longSide, shortSide);
		this.addElement(entrance);
		exit = new Exit(entrance.getPos(), longSide, shortSide);
		this.addElement(exit);
		for (int i = 0; i < (longSide * shortSide); i++) {
			if (((i != (entrance.getPos())) && (i != (exit.getPos())))
					&& (((i / longSide == 0)
							|| (i / longSide == (shortSide - 1))
							|| (i % longSide == 0) || (i % longSide == (longSide - 1))))) {
				Wall w = new Wall(i, longSide, shortSide);
				limits.add(w);
				this.addElement(w);
			}
		}
	}

	public Room(Entrance entrance, Exit exit, ArrayList<Wall> walls,
			int longSide, int shortSide) {
		this.longSide = longSide;
		this.shortSide = shortSide;
		matrix = new Element[this.shortSide][this.longSide];
		this.entrance = new Entrance(entrance.getPos());
		this.addElement(entrance);
		this.exit = new Exit(exit.getPos());
		this.addElement(exit);
		for (Wall w : walls) {
			limits.add(w);
			this.addElement(w);
		}
	}

	public int getLongSide() {
		return longSide;
	}

	public int getShortSide() {
		return shortSide;
	}

	public ArrayList<Wall> getLimits() {
		return limits;
	}

	public void setEntrance(Entrance entrance) {
		this.entrance = entrance;
	}

	public Entrance getEntrance() {
		return entrance;
	}

	public void setExit(Exit exit) {
		this.exit = exit;
	}

	public Exit getExit() {
		return exit;
	}

	public Element[][] getMatrix() {
		return matrix;
	}

	public Element getElement(int x, int y) {
		return matrix[x][y];
	}

	public void addElement(Element e) {
		intAddElement(e);
		if (matrix[entrance.getPos() / longSide][entrance.getPos() % longSide] == null)
			intAddElement(entrance);
	}

	public void removeElement(Element e) {
		intRemoveElement(e);
	}

	public void printRoom() {
		for (int i = 0; i < (longSide * shortSide); i++) {
			if (matrix[i / longSide][i % longSide] instanceof Wall) {
				if ((i / longSide == 0) || (i / longSide == (shortSide - 1))) {
					System.out.printf(" = ");
				} else
					System.out.printf(" | ");
			} else if (matrix[i / longSide][i % longSide] instanceof Door)
				System.out.printf(" + ");
			else if (matrix[i / longSide][i % longSide] instanceof Potion)
				System.out.printf(" * ");
			else if (matrix[i / longSide][i % longSide] instanceof Player)
				System.out.printf(" @ ");
			else if (matrix[i / longSide][i % longSide] instanceof Monster)
				System.out.printf(" M ");
			else
				System.out.printf(" - ");
			if (i % longSide == longSide - 1)
				System.out.printf("\n");
		}
		System.out.printf("\n");
	}

	public void printRoomHard() {
		for (int i = 0; i < (longSide * shortSide); i++) {
			if (matrix[i / longSide][i % longSide] != null) {
				if (matrix[i / longSide][i % longSide].isVisible()) {
					if (matrix[i / longSide][i % longSide] instanceof Wall) {
						if ((i / longSide == 0)
								|| (i / longSide == (shortSide - 1))) {
							System.out.printf(" = ");
						} else
							System.out.printf(" | ");
					} else if (matrix[i / longSide][i % longSide] instanceof Door)
						System.out.printf(" + ");
					else if (matrix[i / longSide][i % longSide] instanceof Potion)
						System.out.printf(" * ");
					else if (matrix[i / longSide][i % longSide] instanceof Player)
						System.out.printf(" @ ");
					else if (matrix[i / longSide][i % longSide] instanceof Monster)
						System.out.printf(" M ");
					else
						System.out.printf(" - ");
					if (i % longSide == longSide - 1)
						System.out.printf("\n");
				} else
					System.out.printf("   ");
			} else
				System.out.printf("   ");
		}
		System.out.printf("\n");
	}

	@Override
	public String toString() {
		return "Room [longSide=\"" + longSide + "\", shortSide=\"" + shortSide + "\"]";
	}

	private void intAddElement(Element e) {
		matrix[e.getPos() / longSide][e.getPos() % longSide] = e;
	}

	private void intRemoveElement(Element e) {
		matrix[e.getPos() / longSide][e.getPos() % longSide] = null;
	}
}
